<?php

namespace app\admin\controller\scanwork;

use app\common\controller\Backend;
use app\admin\model\scanwork\QualityRecord as QualityRecordModel;
use app\admin\model\scanwork\QualityStandard;
use app\admin\model\scanwork\Report;
use think\Db;
use think\exception\DbException;
use think\exception\ValidateException;

/**
 * 质检记录管理
 */
class QualityRecord extends Backend
{
    /**
     * QualityRecord模型对象
     * @var \app\admin\model\scanwork\QualityRecord
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new QualityRecordModel;
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自定义
     * 如果需要自定义，请复制application/admin/library/traits/Backend.php中对应的方法来修改
     */

    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            // 手动处理参数，避免buildparams()的闭包问题
            $sort = $this->request->get('sort', 'id');
            $order = $this->request->get('order', 'desc');
            $offset = $this->request->get('offset', 0);
            $limit = $this->request->get('limit', 10);
            
            // 构建基础查询条件
            $where = [];
            
            // 处理搜索条件
            $filter = $this->request->get('filter', '{}');
            $filter = json_decode($filter, true);
            if (is_array($filter)) {
                foreach ($filter as $key => $value) {
                    if ($value !== '' && $value !== null) {
                        $where[$key] = ['like', '%' . $value . '%'];
                    }
                }
            }
            
            $list = $this->model
                ->with(['report', 'report.allocation', 'report.allocation.process', 'report.allocation.model', 'report.allocation.order', 'report.allocation.plan', 'report.user', 'standard', 'qualityUser'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            foreach ($list as $row) {
                $row->visible(['id', 'report_id', 'standard_id', 'quality_user_id', 'overall_result', 'handle_method', 'check_time', 'remark', 'createtime']);
                if ($row->report) {
                    $row->visible(['report']);
                    $row->getRelation('report')->visible(['report_code', 'quantity', 'remark', 'allocation', 'user']);
                    if ($row->report->allocation) {
                        $row->report->visible(['allocation']);
                        $row->report->getRelation('allocation')->visible(['quantity', 'process', 'model', 'order', 'plan']);
                        if ($row->report->allocation->process) {
                            $row->report->allocation->visible(['process']);
                            $row->report->allocation->getRelation('process')->visible(['name']);
                        }
                        if ($row->report->allocation->model) {
                            $row->report->allocation->visible(['model']);
                            $row->report->allocation->getRelation('model')->visible(['name']);
                        }
                        if ($row->report->allocation->order) {
                            $row->report->allocation->visible(['order']);
                            $row->report->allocation->getRelation('order')->visible(['order_name']);
                        }
                        if ($row->report->allocation->plan) {
                            $row->report->allocation->visible(['plan']);
                            $row->report->allocation->getRelation('plan')->visible(['plan_code']);
                        }
                    }
                    if ($row->report->user) {
                        $row->report->visible(['user']);
                        $row->report->getRelation('user')->visible(['nickname', 'username']);
                    }
                }
                if ($row->standard) {
                    $row->visible(['standard']);
                    $row->getRelation('standard')->visible(['name']);
                }
                if ($row->qualityUser) {
                    $row->visible(['qualityUser']);
                    $row->getRelation('qualityUser')->visible(['nickname', 'username']);
                }
            }
            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 查看详情
     */
    public function detail($ids = null)
    {
        $row = $this->model->with([
            'report', 
            'report.allocation', 
            'report.allocation.process', 
            'report.allocation.model', 
            'report.allocation.order',
            'report.allocation.plan',
            'report.user',
            'standard', 
            'qualityUser', 
            'images'
        ])->find($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        
        // 解析JSON字段
        $row->check_results_array = $row->getCheckResultsArray();
        $row->unqualified_items_array = $row->getUnqualifiedItemsArray();
        $row->unqualified_reasons_array = $row->getUnqualifiedReasonsArray();
        
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 执行质检
     */
    public function execute($ids = null)
    {
        $ids = $ids ?: $this->request->get('id');
        if (!$ids) {
            $this->error('参数错误');
        }
        
        $report = Report::with([
            'allocation', 
            'allocation.process', 
            'allocation.model',
            'allocation.order',
            'allocation.plan',
            'user'
        ])->find($ids);
        if (!$report) {
            $this->error(__('No Results were found'));
        }

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $result = false;
                Db::startTrans();
                try {
                    // 获取质检标准
                    $standard = QualityStandard::getByProcessId($report->allocation->process_id);
                    if (!$standard) {
                        $standard = QualityStandard::getGeneralStandard();
                    }
                    
                    if (!$standard) {
                        throw new \Exception('未找到对应的质检标准');
                    }

                    // 创建质检记录
                    $qualityRecord = new QualityRecordModel();
                    $qualityRecord->report_id = $report->id;
                    $qualityRecord->standard_id = $standard->id;
                    $qualityRecord->quality_user_id = $this->auth->id;
                    
                    // 安全获取检查结果，避免undefined array key错误
                    $checkResults = isset($params['check_results']) && is_array($params['check_results']) ? $params['check_results'] : [];
                    $qualityRecord->check_results = json_encode($checkResults);
                    $qualityRecord->overall_result = $qualityRecord->calculateOverallResult($checkResults);
                    $qualityRecord->check_time = time();
                    $qualityRecord->remark = $params['remark'] ?? '';
                    
                    // 设置处理方式
                    $qualityRecord->handle_method = $params['handle_method'] ?? 0; // 默认合格
                    
                    // 如果有不合格项目，记录详细信息
                    if ($qualityRecord->overall_result == 2) {
                        $unqualifiedItems = $qualityRecord->getUnqualifiedItems($checkResults);
                        $qualityRecord->unqualified_items = json_encode($unqualifiedItems);
                    }
                    
                    $result = $qualityRecord->save();
                    
                    // 更新报工质检结果（不影响报工状态）
                    $report->quality_result = $qualityRecord->overall_result;
                    $report->quality_remark = $params['remark'] ?? '';
                    $report->save();
                    
                    // 如果质检合格或让步接收，创建质检入库记录
                    if ($qualityRecord->overall_result == 1 || $qualityRecord->handle_method == 3) {
                        $this->createQualityInventory($qualityRecord, $report);
                    }
                    
                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        
        // 获取质检标准
        $standard = QualityStandard::getByProcessId($report->allocation->process_id);
        if (!$standard) {
            $standard = QualityStandard::getGeneralStandard();
        }
        
        // 解析检查项目数据
        $checkItems = [];
        if ($standard && $standard->check_items) {
            $checkItems = json_decode($standard->check_items, true);
            if (!$checkItems) {
                $checkItems = [];
            }
        }
        
        $this->view->assign("report", $report);
        $this->view->assign("standard", $standard);
        $this->view->assign("checkItems", $checkItems);
        return $this->view->fetch();
    }

    /**
     * 获取质检标准数据
     */
    public function getStandardData()
    {
        $id = $this->request->get('id');
        if (!$id) {
            $this->error('参数错误');
        }
        
        $report = Report::with([
            'allocation', 
            'allocation.process'
        ])->find($id);
        
        if (!$report) {
            $this->error('报工记录不存在');
        }
        
        // 获取质检标准
        $standard = QualityStandard::getByProcessId($report->allocation->process_id);
        if (!$standard) {
            $standard = QualityStandard::getGeneralStandard();
        }
        
        if (!$standard) {
            $this->error('未找到对应的质检标准');
        }
        
        // 解析检查项目JSON数据
        $checkItems = json_decode($standard->check_items, true);
        if (!$checkItems) {
            $checkItems = [];
        }
        
        // 直接返回JSON数据
        $result = [
            'code' => 1,
            'msg' => '获取成功',
            'data' => [
                'check_items' => $checkItems,
                'standard_name' => $standard->name
            ]
        ];
        
        \think\Log::info('getStandardData 返回数据: ' . json_encode($result));
        
        return json($result);
    }
    
    /**
     * 获取待质检列表
     */
    public function pending()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            // 手动处理参数，避免buildparams()的闭包问题
            $sort = $this->request->get('sort', 'id');
            $order = $this->request->get('order', 'desc');
            $offset = $this->request->get('offset', 0);
            $limit = $this->request->get('limit', 10);
            
            // 构建基础查询条件 - 显示所有报工数据，排除已质检的
            $where = [];
            
            // 处理搜索条件
            $filter = $this->request->get('filter', '{}');
            $filter = json_decode($filter, true);
            if (is_array($filter)) {
                foreach ($filter as $key => $value) {
                    if ($value !== '' && $value !== null) {
                        $where[$key] = ['like', '%' . $value . '%'];
                    }
                }
            }
            
            $list = Report::with([
                'allocation', 
                'allocation.process', 
                'allocation.model', 
                'allocation.order',
                'allocation.plan',
                'user'
            ])
                ->where($where)
                ->where('id', 'not in', function($query) {
                    $query->table('fa_scanwork_quality_record')->field('report_id');
                })
                ->order($sort, $order)
                ->paginate($limit);

            foreach ($list as $row) {
                $row->visible(['id', 'quantity', 'remark', 'createtime']);
                if ($row->allocation) {
                    $row->visible(['allocation']);
                    $row->getRelation('allocation')->visible(['quantity']);
                    if ($row->allocation->process) {
                        $row->allocation->visible(['process']);
                    }
                    if ($row->allocation->model) {
                        $row->allocation->visible(['model']);
                    }
                    if ($row->allocation->order) {
                        $row->allocation->visible(['order']);
                    }
                    if ($row->allocation->plan) {
                        $row->allocation->visible(['plan']);
                    }
                }
                if ($row->user) {
                    $row->visible(['user']);
                    $row->getRelation('user')->visible(['nickname', 'username']);
                }
            }
            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }
    
    /**
     * 创建质检入库记录
     */
    private function createQualityInventory($qualityRecord, $report)
    {
        try {
            // 检查是否已经创建过质检入库记录
            $existingInventory = \think\Db::name('scanwork_quality_inventory')
                ->where('report_id', $report->id)
                ->find();
            
            if ($existingInventory) {
                return; // 已存在，直接返回
            }
            
            // 创建质检入库记录
            $inventoryData = [
                'report_id' => $report->id,
                'allocation_id' => $report->allocation_id,
                'order_id' => $report->allocation->order_id,
                'model_id' => $report->allocation->model_id,
                'process_id' => $report->allocation->process_id,
                'user_id' => $report->user_id,
                'quality_user_id' => $qualityRecord->quality_user_id,
                'standard_id' => $qualityRecord->standard_id,
                'quantity' => $report->quantity,
                'qualified_quantity' => $report->quantity,
                'unqualified_quantity' => 0,
                'quality_result' => 1, // 合格
                'check_results' => $qualityRecord->check_results,
                'quality_remark' => $qualityRecord->remark,
                'inventory_status' => 0, // 待入库
                'check_time' => $qualityRecord->check_time,
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            \think\Db::name('scanwork_quality_inventory')->insert($inventoryData);
            
            // 更新质检记录的入库状态
            $qualityRecord->inventory_id = \think\Db::name('scanwork_quality_inventory')->getLastInsID();
            $qualityRecord->inventory_status = 0; // 待入库
            $qualityRecord->save();
            
        } catch (\Exception $e) {
            // 静默处理异常，不影响质检流程
            \think\Log::error('创建质检入库记录失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 执行入库
     */
    public function inventory()
    {
        $id = $this->request->post('id');
        if (!$id) {
            $this->error('参数错误');
        }

        $qualityRecord = $this->model->get($id);
        if (!$qualityRecord) {
            $this->error('质检记录不存在');
        }

        if ($qualityRecord->overall_result != 1) {
            $this->error('只有质检合格的产品才能入库');
        }

        try {
            \think\Db::startTrans();
            
            // 更新质检入库记录状态
            \think\Db::name('scanwork_quality_inventory')
                ->where('report_id', $qualityRecord->report_id)
                ->update([
                    'inventory_status' => 1, // 已入库
                    'inventory_time' => time(),
                    'inventory_user_id' => $this->auth->id,
                    'updatetime' => time()
                ]);
            
            // 更新质检记录状态
            $qualityRecord->inventory_status = 1; // 已入库
            $qualityRecord->save();
            
            \think\Db::commit();
            $this->success('入库成功');
        } catch (\Exception $e) {
            \think\Db::rollback();
            $this->error('入库失败：' . $e->getMessage());
        }
    }
    
    /**
     * 质检统计分析
     */
    public function statistics()
    {
        if ($this->request->isAjax()) {
            $type = $this->request->get('type', 'overview');
            
            switch ($type) {
                case 'overview':
                    // 总体统计
                    return json($this->getOverviewStatistics());
                case 'trend':
                    // 趋势分析
                    return json($this->getTrendStatistics());
                case 'process':
                    // 工序统计
                    return json($this->getProcessStatistics());
                case 'defect':
                    // 不合格项统计
                    return json($this->getDefectStatistics());
                default:
                    $this->error('未知的统计类型');
            }
        }
        return $this->view->fetch();
    }
    
    /**
     * 获取总体统计数据
     */
    private function getOverviewStatistics()
    {
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-d'));
        
        $startTime = strtotime($startDate . ' 00:00:00');
        $endTime = strtotime($endDate . ' 23:59:59');
        
        \think\Log::info('统计查询 - 开始时间: ' . $startDate . ' (' . $startTime . '), 结束时间: ' . $endDate . ' (' . $endTime . ')');
        
        // 总质检数
        $total = $this->model
            ->where('check_time', 'between', [$startTime, $endTime])
            ->count();
        
        \think\Log::info('总质检数: ' . $total);
        
        // 合格数
        $qualified = $this->model
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 1)
            ->count();
        
        // 不合格数
        $unqualified = $this->model
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 2)
            ->count();
        
        // 让步接收数
        $concession = $this->model
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 3)
            ->count();
        
        // 合格率
        $qualifiedRate = $total > 0 ? round($qualified / $total * 100, 2) : 0;
        
        $result = [
            'code' => 1,
            'data' => [
                'total' => $total,
                'qualified' => $qualified,
                'unqualified' => $unqualified,
                'concession' => $concession,
                'qualified_rate' => $qualifiedRate
            ]
        ];
        
        \think\Log::info('统计结果: ' . json_encode($result));
        
        return $result;
    }
    
    /**
     * 获取趋势统计数据
     */
    private function getTrendStatistics()
    {
        $days = $this->request->get('days', 30);
        $endDate = date('Y-m-d');
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $startTime = strtotime($startDate . ' 00:00:00');
        $endTime = strtotime($endDate . ' 23:59:59');
        
        $records = $this->model
            ->field('DATE(FROM_UNIXTIME(check_time)) as date, overall_result, COUNT(*) as count')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->group('DATE(FROM_UNIXTIME(check_time)), overall_result')
            ->select();
        
        // 组织数据
        $dates = [];
        $qualifiedData = [];
        $unqualifiedData = [];
        
        for ($i = 0; $i < $days; $i++) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $dates[] = $date;
            $qualifiedData[$date] = 0;
            $unqualifiedData[$date] = 0;
        }
        
        foreach ($records as $record) {
            if ($record['overall_result'] == 1) {
                $qualifiedData[$record['date']] = $record['count'];
            } else if ($record['overall_result'] == 2) {
                $unqualifiedData[$record['date']] = $record['count'];
            }
        }
        
        return [
            'code' => 1,
            'data' => [
                'dates' => array_reverse($dates),
                'qualified' => array_values(array_reverse($qualifiedData)),
                'unqualified' => array_values(array_reverse($unqualifiedData))
            ]
        ];
    }
    
    /**
     * 获取工序统计数据
     */
    private function getProcessStatistics()
    {
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-d'));
        
        $startTime = strtotime($startDate . ' 00:00:00');
        $endTime = strtotime($endDate . ' 23:59:59');
        
        $sql = "SELECT 
                    p.name as process_name,
                    COUNT(*) as total,
                    SUM(CASE WHEN qr.overall_result = 1 THEN 1 ELSE 0 END) as qualified,
                    SUM(CASE WHEN qr.overall_result = 2 THEN 1 ELSE 0 END) as unqualified
                FROM fa_scanwork_quality_record qr
                LEFT JOIN fa_scanwork_report r ON qr.report_id = r.id
                LEFT JOIN fa_scanwork_allocation a ON r.allocation_id = a.id
                LEFT JOIN fa_scanwork_process p ON a.process_id = p.id
                WHERE qr.check_time BETWEEN {$startTime} AND {$endTime}
                GROUP BY p.id, p.name
                ORDER BY total DESC
                LIMIT 10";
        
        $result = Db::query($sql);
        
        return [
            'code' => 1,
            'data' => $result
        ];
    }
    
    /**
     * 获取不合格项统计
     */
    private function getDefectStatistics()
    {
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-d'));
        
        $startTime = strtotime($startDate . ' 00:00:00');
        $endTime = strtotime($endDate . ' 23:59:59');
        
        $records = $this->model
            ->field('unqualified_items')
            ->where('check_time', 'between', [$startTime, $endTime])
            ->where('overall_result', 2)
            ->where('unqualified_items', 'neq', '')
            ->select();
        
        $defectStats = [];
        foreach ($records as $record) {
            $items = json_decode($record['unqualified_items'], true);
            if (is_array($items)) {
                foreach ($items as $item) {
                    $key = $item['项目'] ?? '未知';
                    if (!isset($defectStats[$key])) {
                        $defectStats[$key] = 0;
                    }
                    $defectStats[$key]++;
                }
            }
        }
        
        // 排序并取TOP10
        arsort($defectStats);
        $defectStats = array_slice($defectStats, 0, 10, true);
        
        return [
            'code' => 1,
            'data' => [
                'items' => array_keys($defectStats),
                'counts' => array_values($defectStats)
            ]
        ];
    }
}
